using WenYu.Core.Lexer;

namespace WenYu.Core.Errors
{
    /// <summary>
    /// Parser 错误提供者 - 提供语法错误的便捷构建方法
    /// </summary>
    public static class ParserErrors
    {
        /// <summary>
        /// S001: 缺少语句结束符
        /// </summary>
        public static CompileError MissingPeriod(Token token, string sourceCode, string filePath = "")
        {
            return ErrorBuilder.Create("S001", "缺少语句结束符")
                .AtPosition(token.Line, token.Column)
                .InFile(filePath)
                .WithSource(sourceCode)
                .WithExplanation("在文语中，每条语句必须以句号（。）结束。这就像写作文时，每句话结束要加句号一样。")
                .AddSuggestion($"在第{token.Line}行末尾加上中文句号（。）")
                .AddSuggestion($"完整的语句应该是：{GetCurrentLineWithPeriod(sourceCode, token.Line)}")
                .AddKnowledgeWithDocUrl("查看【01-基础语法】了解语句规则")
                .AddKnowledge("句号可以用中文（。）或英文（.）")
                .AddHelp("输入法快速输入句号：按句号键即可")
                .AddExampleHelp("examples/hello.wy")
                .Build();
        }
        
        /// <summary>
        /// S002: 括号不匹配
        /// </summary>
        public static CompileError MismatchedParentheses(Token token, string expected, string sourceCode, string filePath = "")
        {
            return ErrorBuilder.Create("S002", "括号不匹配")
                .AtPosition(token.Line, token.Column)
                .InFile(filePath)
                .WithSource(sourceCode)
                .WithExplanation($"每个左括号都需要有对应的右括号。这里期望找到 '{expected}'，但找到了 '{token.Value}'。")
                .AddSuggestion($"检查第{token.Line}行的括号是否配对")
                .AddSuggestion("确保每个 '（' 都有对应的 '）'")
                .AddSuggestion("确保每个 '{' 都有对应的 '}'")
                .AddKnowledgeWithDocUrl("查看【01-基础语法】了解括号使用规则")
                .AddKnowledge("中英文括号都支持：（）或()")
                .AddHelp("提示：可以数一数左括号和右括号的数量是否相等")
                .Build();
        }
        
        /// <summary>
        /// S003: 缺少 '则' 关键字
        /// </summary>
        public static CompileError MissingThen(Token token, string sourceCode, string filePath = "")
        {
            return ErrorBuilder.Create("S003", "缺少 '则' 关键字")
                .AtPosition(token.Line, token.Column)
                .InFile(filePath)
                .WithSource(sourceCode)
                .WithExplanation("在条件语句中，'若' 后面的条件表达式必须跟 '则' 关键字，然后才是代码块。")
                .AddSuggestion($"在第{token.Line}行的条件后面加上 '则'")
                .AddSuggestion("完整的语法是：若 <条件> 则 { <代码> }")
                .AddKnowledgeWithDocUrl("查看【04-控制流】了解条件语句")
                .AddHelp("示例：若 年龄 》 18 则 { 输出（\"成年了\"）。}")
                .Build();
        }
        
        /// <summary>
        /// S004: 条件缺失
        /// </summary>
        public static CompileError MissingCondition(Token token, string sourceCode, string filePath = "")
        {
            return ErrorBuilder.Create("S004", "条件表达式缺失")
                .AtPosition(token.Line, token.Column)
                .InFile(filePath)
                .WithSource(sourceCode)
                .WithExplanation("'若' 关键字后面必须有一个条件表达式，用来判断是否执行代码块。")
                .AddSuggestion("在 '若' 和 '则' 之间添加条件表达式")
                .AddSuggestion("示例：若 年龄 》 18 则 { ... }")
                .AddKnowledgeWithDocUrl("查看【04-控制流】了解条件语句")
                .AddKnowledgeWithDocUrl("查看【03-运算符】了解比较运算符")
                .AddHelp("常用比较运算符：》（大于）、《（小于）、同（等于）")
                .Build();
        }
        
        /// <summary>
        /// S005: 函数定义格式错误
        /// </summary>
        public static CompileError InvalidFunctionDefinition(Token token, string sourceCode, string filePath = "")
        {
            return ErrorBuilder.Create("S005", "函数定义格式错误")
                .AtPosition(token.Line, token.Column)
                .InFile(filePath)
                .WithSource(sourceCode)
                .WithExplanation("函数定义的格式不正确。文语中函数定义的完整格式是：[参数列表] 求 [返回类型] 之 法 [函数名] { [函数体] }")
                .AddSuggestion("检查函数定义的语法是否正确")
                .AddSuggestion("示例（无参数）：求 整型 之 法 获取年龄 { 得 18。}")
                .AddSuggestion("示例（有参数）：整型 甲，整型 乙 求 整型 之 法 求和 { 得 甲 + 乙。}")
                .AddKnowledgeWithDocUrl("查看【05-函数】了解函数定义")
                .AddHelp("注意：'求'、'之'、'法' 是关键字，不要遗漏")
                .Build();
        }
        
        /// <summary>
        /// S006: 期望特定的Token类型
        /// </summary>
        public static CompileError ExpectedToken(Token actual, string expectedType, string sourceCode, string filePath = "")
        {
            return ErrorBuilder.Create("S006", $"期望 {expectedType}")
                .AtPosition(actual.Line, actual.Column)
                .InFile(filePath)
                .WithSource(sourceCode)
                .WithExplanation($"这里期望找到 {expectedType}，但实际找到了 '{actual.Value}'。")
                .AddSuggestion($"检查第{actual.Line}行的语法")
                .AddSuggestion("确保所有关键字和符号都使用正确")
                .AddKnowledgeWithUrl("查看【08-关键字速查表】查询所有关键字", 
                    ErrorDocumentationConfig.GetKeywordReferenceUrl())
                .Build();
        }
        
        // ========== 私有辅助方法 ==========
        
        /// <summary>
        /// 获取当前行并添加句号
        /// </summary>
        private static string GetCurrentLineWithPeriod(string sourceCode, int lineNumber)
        {
            if (string.IsNullOrEmpty(sourceCode))
                return "";
            
            var lines = sourceCode.Split('\n');
            if (lineNumber < 1 || lineNumber > lines.Length)
                return "";
            
            var line = lines[lineNumber - 1].TrimEnd();
            return line + "。";
        }
    }
}

